package com.weilele.mvvm.view

import android.content.Context
import android.graphics.Rect
import android.graphics.RectF
import android.util.AttributeSet
import android.view.*
import androidx.core.view.NestedScrollingChildHelper
import androidx.core.view.ViewCompat
import androidx.core.view.children
import com.weilele.mvvm.utils.activity.hadScrollToBottom
import com.weilele.mvvm.utils.activity.hadScrollToEnd
import com.weilele.mvvm.utils.activity.hadScrollToStart
import com.weilele.mvvm.utils.activity.hadScrollToTop
import com.weilele.mvvm.widget.BaseLinearLayout
import kotlin.math.abs

/**
 *  支持嵌套滚动的子view
 */
class UnConsumedView : BaseLinearLayout {
    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
            context,
            attrs,
            defStyleAttr
    )

    private val config by lazy { ViewConfiguration.get(context) }
    private val scaledPagingTouchSlop by lazy { config.scaledPagingTouchSlop }
    private val scaledMinimumFlingVelocity by lazy { config.scaledMinimumFlingVelocity }
    private val scaledMaximumFlingVelocity by lazy { config.scaledMaximumFlingVelocity.toFloat() }

    private var velocityTracker: VelocityTracker? = null
        get() {
            if (field == null) {
                field = VelocityTracker.obtain()
            }
            return field
        }
    private val helper by lazy { NestedScrollingChildHelper(this) }

    init {
        isNestedScrollingEnabled = true
        helper.isNestedScrollingEnabled = true
    }


    private var downX = 0f
    private var downY = 0f
    override fun onTouchEvent(event: MotionEvent?): Boolean {
        velocityTracker?.addMovement(event)
        when (event?.action) {
            MotionEvent.ACTION_DOWN -> {
                downX = event.rawX
                downY = event.rawY
                helper.startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL)
                return true
            }
            MotionEvent.ACTION_MOVE -> {
                if (downX == 0f && downY == 0f) {
                    downX = event.rawX
                    downY = event.rawY
                    helper.startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL)
                } else {
                    val offX = downX - event.rawX
                    val offY = downY - event.rawY
                    val offXInt = offX.toInt()
                    val offYInt = offY.toInt()
                    helper.dispatchNestedPreScroll(
                            offXInt,
                            offYInt,
                            null,
                            null
                    )
                    downX = event.rawX + offX - offXInt.toFloat()
                    downY = event.rawY + offY - offYInt.toFloat()
                }
            }
            MotionEvent.ACTION_UP,
            MotionEvent.ACTION_CANCEL -> {
                if (downX == 0f && downY == 0f) {
                    return super.onTouchEvent(event)
                }
                velocityTracker?.let {
                    velocityTracker = null
                    it.computeCurrentVelocity(1000, scaledMaximumFlingVelocity)
                    if (abs(it.yVelocity) > scaledMinimumFlingVelocity) {
                        helper.dispatchNestedPreFling(
                                -it.xVelocity, -it.yVelocity
                        )
                    }
                    it.clear()
                    it.recycle()
                }
                downX = 0f
                downY = 0f
                helper.stopNestedScroll()
            }
        }
        return super.onTouchEvent(event)
    }

    //---------------------------------对子view是否需要拦截做判断----------------------------------------
    private var touchX = 0f
    private var touchY = 0f
    private var isHadTouchSlop = false

    private fun getTouchView(x: Int, y: Int): View? {
        val rect = Rect()
        children.forEach {
            rect.set(it.left, it.top, it.right, it.bottom)
            if (rect.contains(x, y)) {
                return it
            }
        }
        return null
    }

    override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
        when (ev?.action) {
            MotionEvent.ACTION_DOWN -> {
                isHadTouchSlop = false
                touchX = ev.rawX
                touchY = ev.rawY
            }
            MotionEvent.ACTION_MOVE -> {
                if (isHadTouchSlop) {
                    return true
                }
                val offX = touchX - ev.rawX
                val offY = touchY - ev.rawY
                val onlyChild = getTouchView(ev.x.toInt(), ev.y.toInt())
                if ((offX > scaledPagingTouchSlop && onlyChild?.hadScrollToEnd() == true)
                        || (offX < -scaledPagingTouchSlop && onlyChild?.hadScrollToStart() == true)
                        || (offY > scaledPagingTouchSlop && onlyChild?.hadScrollToBottom() == true)
                        || (offY < -scaledPagingTouchSlop && onlyChild?.hadScrollToTop() == true)
                ) {
                    //发生了滑动
                    isHadTouchSlop = true
                    return true
                }
            }
            MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_UP -> {
                if (isHadTouchSlop) {
                    isHadTouchSlop = false
                    return true
                }
            }
        }
        return super.onInterceptTouchEvent(ev)
    }
}